const {
	reqGet,
	reqPost,
} = require('@utils/request')
const {
	$U_UserInfo,
	$U_SetItem,
	$U_GetItem,
} = require('@utils/storage')
const {
	setFormEdit,
	setBtnEdit,
	randomId,
} = require('./api-utils')
const {
	apiParameterHistory,
	importJSONHistory,
} = require('./api-utils-history-2x')
const {
	editMethod,
} = require('./api-button-methods-2x')

module.exports = {

	/**
	 * 编辑请求/响应参数表单
	 * @param {[type]} flag [description]
	 */
	openParameterDialog(flag, paramStatus) {
		endEditRow(this, flag)
		let {
			store,
			parameterDialog,
			parameterForm,
		} = this
		if (!store.isLock)
			return switchEditModeHint.call(this)
		let paramsComp = this[`${flag}ParamsComp`]
		store._flag = flag
		store.paramStatus = paramStatus || ''
		let paramData = {
			name: '',
			mandatory: 'O',
			type: 'string',
			content: '',
			remark: '',
		}
		if (paramStatus == 'update') {
			paramData = paramsComp.treegrid('getSelected')
		};
		parameterForm.form('load', paramData)
		parameterDialog.dialog('open')
		store.isSave = false
	},

	/**
	 * 保存参数
	 * @return {[type]} [description]
	 */
	saveParameterMethod() {
		let {
			store,
			parameterDialog,
			parameterForm,
			parameterName,
			parameterMandatory,
			parameterType,
			parameterContent,
			parameterRemark,
			treeComp,
		} = this
		let isValid = parameterForm.form('validate');
		if (!isValid)
			return false
		let flag = store._flag
		let paramsComp = this[`${flag}ParamsComp`]
		let paramStatus = store.paramStatus
		let treeId = randomId()
		let content = parameterContent.textbox('getValue')
		let remark = parameterRemark.textbox('getValue')
		content = content.replace(/[`'"\{\}<>\\/]/g, '')
		remark = remark.replace(/[`'"\{\}<>\\/]/g, '')
		let row = {
			name: parameterName.textbox('getValue'),
			type: parameterType.combobox('getValue'),
			mandatory: parameterMandatory.combobox('getValue'),
			content,
			remark,
		}
		let editNode = {
			data: [{
				_treeId_: treeId,
			}]
		}
		if (paramStatus == 'child') {
			let current = store[`${flag}Current`]
			let parentRow = current.parentRow
			editNode.parent = parentRow._treeId_
		}
		let oldValues = null
		if (paramStatus == 'update') {
			let selected = paramsComp.treegrid('getSelected')
			oldValues = {
				_treeId_: selected._treeId_,
				content: selected.content,
				mandatory: selected.mandatory,
				name: selected.name,
				remark: selected.remark,
				type: selected.type,
			}
			treeId = selected._treeId_
			paramsComp.treegrid('update', {
				id: treeId,
				row,
			})
		} else {
			$.extend(editNode.data[0], row)
			paramsComp.treegrid('append', editNode);
		}
		let moduleId = getModuleId(apiComp);
		// 记录参数/属性添加
		if (paramStatus == 'add' || paramStatus == 'child')
			apiParameterHistory.call(this, flag, 'add', editNode.data[0], null, moduleId);
		// 记录参数修改
		row._treeId_ = treeId
		if (paramStatus == 'update')
			apiParameterHistory.call(this, flag, 'modify', oldValues, row, moduleId);
		parameterDialog.dialog('close');
	},

	/**
	 * 导入请求JSON格式数据
	 * @return {[type]} [description]
	 */
	importJSON(flag) {
		endEditRow(this, flag)
		let {
			store,
			jsonDialog,
			jsonText,
			alertDialog,
			alertText,
		} = this
		if (!store.isLock) {
			// return switchEditModeHint.call(this)
			let paramsComp = this[`${flag}ParamsComp`]
			let data = paramsComp.treegrid('getData')
			let JSONData = {}
			parseParameterToJSON(JSONData, data)
			alertDialog.dialog('setTitle', '提示')
			alertText.textbox('setValue', JSON.stringify(JSONData, null, 5) || "");
			alertDialog.dialog('open');
			return;
		}
		store._flag = flag
		jsonText.textbox('setValue', '')
		jsonDialog.dialog('open')
		store.isSave = false
	},

	/**
	 * 双击参数编辑事件
	 * @param  {[type]} row [description]
	 * @return {[type]}     [description]
	 */
	onBeforeEdit(row) {
		let {
			store
		} = this
		store.tmpOldParameterValues = {
			_treeId_: row._treeId_,
			content: row.content,
			mandatory: row.mandatory,
			name: row.name,
			remark: row.remark,
			type: row.type,
		}
	},

	/**
	 * 参数编辑完成后
	 * @param  {[type]} row     [description]
	 * @param  {[type]} changes [description]
	 * @return {[type]}         [description]
	 */
	onAfterEdit(row, changes, flag) {
		let {
			store,
			treeComp,
		} = this
		let moduleId = getModuleId(this);
		apiParameterHistory.call(this, flag, 'modify', store.tmpOldParameterValues, row, moduleId);
	},

	addParameterChildren(e, flag) {
		let {
			store,
			treeComp,
		} = this;
		let paramsComp = this[`${flag}ParamsComp`]
		let current = store[`${flag}Current`]
		let parentRow = current.parentRow
		let newId = randomId()
		paramsComp.treegrid('append', {
			parent: parentRow._treeId_,
			data: [{
				_treeId_: newId,
				name: '',
				type: 'string',
				content: '',
				remark: '',
				mandatory: 'O',
			}]
		});
		let editRow = {
			_treeId_: newId,
			name: '',
			type: 'string',
			content: '',
			remark: '',
			mandatory: 'O',
		}
		current.editRow = editRow
		paramsComp.treegrid('beginEdit', newId)
		let moduleId = getModuleId(this);
		apiParameterHistory.call(this, flag, 'add', editRow, null, moduleId)
	},

	deleteParameter(e, flag) {
		let {
			store,
		} = this;
		let paramsComp = this[`${flag}ParamsComp`]
		let current = store[`${flag}Current`]
		let parentRow = current.parentRow
		paramsComp.treegrid('remove', parentRow._treeId_)
		let moduleId = getModuleId(this);
		apiParameterHistory.call(this, flag, 'del', parentRow, null, moduleId)
	},

	/**
	 * 右键显示菜单
	 * 1.添加子属性(type = 'object')
	 * 2.删除属性
	 * @param  {[type]} e   [description]
	 * @param  {[type]} row [description]
	 * @return {[type]}     [description]
	 */
	showParameterMenu(e, row, flag) {
		e.preventDefault()
		if (!row)
			return false
		endEditRow(this, flag)
		let {
			store,
		} = this
		if (flag == 'res' && !store.isLock)
			return false
		let paramsComp = this[`${flag}ParamsComp`]
		let paramsMenu = this[`${flag}ParamsMenu`]
		let current = store[`${flag}Current`]
		let addChildItem = paramsMenu.menu('findItem', '添加属性')
		let delItem = paramsMenu.menu('findItem', '删除属性')
		let editValueItem = paramsMenu.menu('findItem', '修改属性值')
		let updateItem = paramsMenu.menu('findItem', '修改参数')
		let lockedShow = store.isLock ? 'showItem' : 'hideItem'
		let addChildItemShow = (store.isLock && (row.type == 'object' || row.type == 'array[object]')) ? 'showItem' : 'hideItem'
		let editValueItemShow = store.isLock ? 'hideItem' : 'showItem'
		paramsMenu.menu(addChildItemShow, addChildItem.target)
		paramsMenu.menu(lockedShow, delItem.target)
		paramsMenu.menu(lockedShow, updateItem.target)
		if (editValueItem && editValueItem.target)
			paramsMenu.menu(editValueItemShow, editValueItem.target)
		paramsMenu.menu('show', {
			left: e.pageX,
			top: e.pageY,
		})
		if (store.isLock)
			current.parentRow = row
		else
			current.editValueRow = row
		paramsComp.treegrid('select', row._treeId_)
	},

	onDblClickRow(row, flag) {
		endEditRow(this, flag)
		let {
			store,
		} = this
		if (!store.isLock)
			return false
		let paramsComp = this[`${flag}ParamsComp`]
		let current = store[`${flag}Current`]
		current.editRow = row
		paramsComp.treegrid('beginEdit', row._treeId_);
	},

	onClickRow(row, flag) {
		endEditRow(this, flag)
	},

	/**
	 * 双击查看参数含义
	 * @param  {[type]} field [description]
	 * @param  {[type]} row   [description]
	 * @return {[type]}       [description]
	 */
	onDblClickCell(field, row) {
		if (this.store.isLock)
			return false
		if (field != 'content' || !row.content || row.content.length < 10)
			return false
		$.messager.alert({
			title: '参数含义',
			msg: row.content || '',
		})
	},

	saveJSONMethod() {
		let {
			store,
			jsonDialog,
		} = this
		let paramsComp = this[`${store._flag}ParamsComp`]
		if (paramsComp) {
			let {
				jsonDialog,
				jsonText,
			} = this
			let JSONData = null
			let value = jsonText.textbox('getValue')
			try {
				JSONData = JSON.parse(value)
			} catch (e) {
				try {
					JSONData = new Function(`return ${value};`)()
				} catch (e) {
					JSONData = null
				}
			}
			if (!JSONData || typeof JSONData != 'object') {
				alert('JSON语法错误')
				return false
			}
			let moduleId = getModuleId(this);
			addJSONParamsComp.call(this, JSONData)
			importJSONHistory.call(this, JSONData, moduleId)
		}
		jsonDialog.dialog('close')
	},

	dialogClose() {
		this.store.isSave = true
	},
}

/**
 * 结束编辑行
 * @param  {[type]} apiComp [description]
 * @return {[type]}         [description]
 */
function endEditRow(apiComp, flag) {
	let {
		store,
	} = apiComp
	let paramsComp = apiComp[`${flag}ParamsComp`]
	let current = store[`${flag}Current`]
	if (current.editRow && current.editRow._treeId_)
		paramsComp.treegrid('endEdit', current.editRow._treeId_)
	if (current.editValueRow && current.editValueRow._treeId_)
		paramsComp.treegrid('endEdit', current.editValueRow._treeId_)
}

/**
 * 添加JSON格式数据
 * @param {[type]} JSONData [description]
 */
function addJSONParamsComp(JSONData) {
	let {
		store,
	} = this
	let treeData = null
	let paramsComp = this[`${store._flag}ParamsComp`]
	if (Array.isArray(JSONData) && JSONData[0]._treeId_) {
		treeData = JSONData
	} else {
		let orgTreeData = paramsComp.treegrid('getData')
		JSONData = JSONData[0] || JSONData
		treeData = parseJSONParameter(JSONData, store._flag)
		treeData = treeData.concat(orgTreeData)
	}
	paramsComp.treegrid('loadData', treeData)
}

/**
 * 解析导入JSON结构数据
 * @param  {[type]} JSONData [description]
 * @return {[type]}          [description]
 */
function parseJSONParameter(JSONData, flag) {
	let paramArr = Object.keys(JSONData)
	let dataArr = []
	for (let i = 0; i < paramArr.length; i++) {
		let key = paramArr[i]
		let val = JSONData[key]
		let type = $._ulType(val)
			// let remark = flag == 'req' && type.indexOf('object') < 0 ? `@value=${val}` : ''
		let remark = ''
		if (type == 'array')
			remark = ''
			// remark = `@value=${JSON.stringify(val)}`
		else if (type == 'object')
			remark = ''
		else if (flag == 'req' && type != 'array' && type != 'object')
			remark = `@value=${val}`
		let data = {
			_treeId_: randomId(),
			name: key,
			type,
			content: '',
			remark,
			mandatory: 'O',
		}
		if (Array.isArray(val) && val.length > 0) {
			let arrVal = val[0]
			data.type = `${type}[${$._ulType(arrVal)}]`
			if (typeof arrVal == 'object') {
				data.children = parseJSONParameter(arrVal)
				data.state = "open"
			}
		} else if (val && typeof val == 'object') {
			data.children = parseJSONParameter(val)
			data.state = "open"
		}
		dataArr.push(data)
	}
	return dataArr
}

/**
 * 切换编辑模式提示
 * @return {[type]} [description]
 */
function switchEditModeHint() {
	let {
		store,
	} = this

	if (store.isHistoryVersion) {
		$.messager.alert({
			title: '提示',
			msg: '当前模式不能操作！',
		})
		return false
	}
	$.messager.confirm({
		title: '提示',
		msg: '当前是非编辑模式！是否切换到编辑模式？',
		fn: (r) => {
			if (r) {
				editMethod.call(this)
			}
		}
	});
	return false
}

/**
 * 把参数列表转换成JSON格式数据
 * @param  {[type]} paramsComp [description]
 * @return {[type]}            [description]
 */
function parseParameterToJSON(JSONData, data) {
	for (let i = 0; i < data.length; i++) {
		let val = data[i]
		let {
			name,
			type,
			remark = '',
		} = val
		let is = false
		remark = remark.replace('@value=', '')
		if (type == 'string' || type == 'number' || type == 'boolean') {
			JSONData[name] = remark
		} else if (type.indexOf('array') > -1 && remark) {
			try {
				remark = JSON.parse(remark)
			} catch (e) {
				remark = ''
			}
			if (remark) {
				JSONData[name] = remark
				continue;
			}
		}
		if (type == 'array[string]' || type == 'array[number]' || type == 'array[boolean]') {
			JSONData[name] = []
		}
		if (val.children) {
			JSONData[name] = {}
			parseParameterToJSON(JSONData[name], val.children)
		}
	}
}

function getModuleId(apiComp) {
	let {
		store,
		treeComp,
	} = apiComp
	let moduleId = ''
	let apiId = store._currentCheckApiDetail && store._currentCheckApiDetail.id;
	let node = treeComp.tree('find', apiId)
	if (node && node.target)
		moduleId = treeComp.tree('getParent', node.target).id
	return moduleId
}